#!/usr/bin/env python
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Play command line script www.playframework.com/

import sys
import os
import os.path
import re

sys.path.append(os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), 'framework', 'pym'))

from play.cmdloader import CommandLoader
from play.application import PlayApplication
from play.utils import *


# ~~~~~~~~~
# Little utility to get command line arguments
def get_opt(args, arg, env):
    s = "--%s=" % arg
    for a in args:
        if a.find(s) == 0:
            env[arg] = a[len(s):]
            args.remove(a)
            # print "~ get_opt: '%s' -> '%s'" % (arg, env[arg])
            break
    

# ~~~~~~~~~
# Main

try:

    play_env = dict()

    # ~~~~~~~~~~~~~~~~~~~~~~ Where is the framework?
    play_env["basedir"] = os.path.normpath(os.path.dirname(os.path.realpath(sys.argv[0])))

    # ~~~~~~~~~~~~~~~~~~~~~~ What is the framework id?
    play_env["id_file"] = os.path.join(play_env['basedir'], 'id')
    if os.path.exists(play_env["id_file"]):
        play_env["id"] = open(play_env["id_file"]).readline().strip()
    else:
        play_env["id"] = ''

    showLogo = sys.argv.count("--silent") == 0

    if showLogo:
        # ~~~~~~~~~~~~~~~~~~~~~~ Display logo
        print r"~        _            _ "
        print r"~  _ __ | | __ _ _  _| |"
        print r"~ | '_ \| |/ _' | || |_|"
        print r"~ |  __/|_|\____|\__ (_)"
        print r"~ |_|            |__/   "
        print r"~"
    else:
        sys.argv.remove("--silent")

    play_version_file = os.path.join(play_env["basedir"], 'framework', 'src', 'play', 'version')
    if not os.path.exists(play_version_file):
        print "~ Oops. %s file not found" % os.path.normpath(os.path.join(play_env["basedir"], 'framework', 'src', 'play', 'version'))
        print "~ Is the framework compiled? "
        print "~"
        sys.exit(-1)

    play_env["version"] = open(play_version_file).readline().strip()

    if showLogo:
        print "~ play! %s, https://www.playframework.com" % (play_env["version"])

    # ~~~~~~~~~~~~~~~~~~~~~~ Where is the application?
    application_path = None
    remaining_args = []
    if len(sys.argv) == 1:
        application_path = os.getcwd()
    if len(sys.argv) == 2:
        application_path = os.getcwd()
        remaining_args = sys.argv[2:]
    if len(sys.argv) > 2:
        if sys.argv[2].startswith('-'):
            application_path = os.getcwd()
            remaining_args = sys.argv[2:]
        else:
            application_path = os.path.normpath(os.path.abspath(sys.argv[2]))
            remaining_args = sys.argv[3:]

    ignoreMissing = False
    if remaining_args.count('--force') == 1:
        remaining_args.remove('--force')
        ignoreMissing = True

    # ~~~~~~~~~~~~~~~~~~~~~~ What is the command?
    if len(sys.argv) > 1:
        play_command = sys.argv[1]
    else:
        play_command = 'none'

    # ~~~~~~~~~~~~~~~~~ Override pid_file
    get_opt(remaining_args, "pid_file", play_env)

    # ~~~~~~~~~~~~~~~~~ Override jvm_version
    get_opt(remaining_args, "jvm_version", play_env)

    # ~~~~~~~~~~~~~~~~~ Override port
    get_opt(remaining_args, "http.port", play_env)
    get_opt(remaining_args, "https.port", play_env)
    get_opt(remaining_args, "jpda.port", play_env)

    # ~~~~~~~~~~~~~~~~~ Override id
    for a in remaining_args:
        if a.find('--%') == 0:
            play_env["id"] = a[3:]
    if remaining_args.count('--%%%s' % play_env["id"]) == 1:
        remaining_args.remove('--%%%s' % play_env["id"])

    if play_command in ['test', 'auto-test', 'autotest'] :
        # If framework-id is not a valid test-id, force it to 'test'
        if not isTestFrameworkId( play_env["id"] ): 
            play_env["id"] = 'test'

    if showLogo:
        if play_env["id"] is not '':
            print "~ framework ID is %s" % play_env["id"]
        print "~"

    # ~~~~~~~~~~~~~~~~~ Checking for disable_random_jpda
    disable_random_jpda = False
    if remaining_args.count('-f') == 1:
        disable_random_jpda = True
        remaining_args.remove('-f')
    play_env["disable_random_jpda"] = disable_random_jpda

    play_app = PlayApplication(application_path, play_env, ignoreMissing)

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # ~~~~~~~~~~~~~~~~~~~~~~ The commands ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    cmdloader = CommandLoader(play_env["basedir"])

    # ~~~~~~~~~~~~~~~~~ Resolve dependencies if needed
    if remaining_args.count('--deps') == 1:
        cmdloader.commands['dependencies'].execute(command='dependencies', app=play_app, args=['--sync'], env=play_env, cmdloader=cmdloader)
        remaining_args.remove('--deps')

    # Load module commands
    if play_app:
        for module in play_app.modules():
            cmdloader.load_play_module(module)

    for module in getWithModules(remaining_args, play_env):
        cmdloader.load_play_module(module)

    if play_command in cmdloader.commands:
        for name in cmdloader.modules:
            module = cmdloader.modules[name]
            if 'before' in dir(module):
                module.before(command=play_command, app=play_app, args=remaining_args, env=play_env)
        status = cmdloader.commands[play_command].execute(command=play_command, app=play_app, args=remaining_args, env=play_env, cmdloader=cmdloader)
        for name in cmdloader.modules:
            module = cmdloader.modules[name]
            if 'after' in dir(module):
                module.after(command=play_command, app=play_app, args=remaining_args, env=play_env)
        sys.exit(status)

    # ~~~~~~~~~~~~~~~~~~~~~~ Invalid command
    print "~ Usage: play cmd [app_path] [--options]"
    print "~ "
    print "~ with,  new      Create a new application"
    print "~        run      Run the application in the current shell"
    print "~        help     Show play help"
    print "~"
    if len(sys.argv) > 1:
        print "~ Invalid command: %s" % sys.argv[1]
        print "~"
    sys.exit(-1)

except KeyboardInterrupt:
    print '~ ...'
    sys.exit(0)
